﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Dynamic;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;

namespace BSF.ServicesResult
{
    /// <summary>
    /// 对外开放平台Api返回结果定义
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public class OpenApiResult<T> : DynamicObject
    {
        /// <summary>
        /// 
        /// </summary>
        public OpenApiResult()
        {
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="data"></param>
        public OpenApiResult(T data)
        {
            this.data = data;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="ret"></param>
        /// <param name="msg"></param>
        public OpenApiResult(int ret, string msg)
        {
            this.ret = ret;
            this.msg = msg;
        }

        /// <summary>
        /// 设置返回错误代码和错误信息
        /// </summary>
        /// <param name="ret"></param>
        /// <param name="msg"></param>
        /// <returns></returns>
        public OpenApiResult<T> Return(int ret, string msg)
        {
            this.ret = ret;
            this.msg = msg;
            return this;
        }

        /// <summary>
        /// 设置返回值的消息体
        /// </summary>
        public T data { get; set; }

        /// <summary>
        /// 返回值，0为正确，其他值表示调用返回错误，具体错误原因参见msg
        /// </summary>
        public int ret { get; set; }

        /// <summary>
        /// 
        /// </summary>
        private string _msg = string.Empty;

        /// <summary>
        /// 接口调用时发生错误的描述
        /// </summary>
        public string msg
        {
            get { return _msg; }
            set { _msg = value; }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public override IEnumerable<string> GetDynamicMemberNames()
        {
            IEnumerable<string> props = new[] { "ret", "msg" };
            if (ret == 0 && data != null)
            {
                if (data is IEnumerable)
                {
                    return props.Concat(new[] { "items" });
                }
                else
                {
                    string[] dynamicProps =
                        data.GetType()
                            .GetProperties(BindingFlags.Instance | BindingFlags.Public)
                            .Select(p => p.Name)
                            .ToArray();
                    props = props.Concat(dynamicProps);
                }
            }
            return props;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="binder"></param>
        /// <param name="result"></param>
        /// <returns></returns>
        public override bool TryGetMember(GetMemberBinder binder, out object result)
        {
            if (data != null)
            {
                if (data is IEnumerable && binder.Name == "items")
                {
                    result = data;
                    return true;
                }
                else
                {
                    var prop = data.GetType().GetProperty(binder.Name);
                    if (prop != null)
                    {
                        result = prop.GetValue(data, null);
                        return true;
                    }
                    else
                    {
                        result = null;
                        return false;
                    }
                }
            }
            return base.TryGetMember(binder, out result);
        }

        /// <summary>
        /// 实际业务数据集合
        /// </summary>
        private T items
        {
            get { return data; }
        }
    }


}
